package top.lingkang.hibernate5.dao.impl;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import top.lingkang.hibernate5.dao.Query;
import top.lingkang.hibernate5.dao.QueryHandler;

import javax.persistence.TransactionRequiredException;
import java.lang.reflect.Method;

/**
 * @author lingkang
 * created by 2023/10/8
 */
public class ModifyingQueryHandler implements QueryHandler {
    private SessionFactory sessionFactory;
    private Query query;
    private boolean isNative;
    private Class<?> returnType;

    public ModifyingQueryHandler(SessionFactory sessionFactory, Query query, boolean isNative, Class<?> returnType) {
        this.sessionFactory = sessionFactory;
        this.query = query;
        this.isNative = isNative;
        this.returnType = returnType;
    }

    @Override
    public Object doQuery(Method method, Object[] args) throws Throwable {
        int executeUpdate = 0;
        try {
            executeUpdate = getQuery(query, args).executeUpdate();
        } catch (TransactionRequiredException tr) {
            throw new TransactionRequiredException("update/delete 还未开启事务：" + tr.getMessage());
        } catch (Exception e) {
            throw e;
        }
        if (returnType == void.class)
            return null;
        else if (returnType == long.class || returnType == Long.class)
            return (long) executeUpdate;
        else
            return executeUpdate;
    }

    private org.hibernate.query.Query getQuery(Query query, Object[] args) {
        Session session = sessionFactory.openSession();
        org.hibernate.query.Query exeQuery = null;
        if (isNative)
            exeQuery = session.createNativeQuery(query.value());
        else
            exeQuery = session.createQuery(query.value());
        if (args != null)
            for (int i = 0; i < args.length; i++)
                exeQuery.setParameter(i + 1, args[i]);
        return exeQuery;
    }
}
